package search;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import models.DealModel;

import com.google.appengine.api.search.Index;
import com.google.appengine.api.search.IndexSpec;
import com.google.appengine.api.search.Query;
import com.google.appengine.api.search.QueryOptions;
import com.google.appengine.api.search.Results;
import com.google.appengine.api.search.ScoredDocument;
import com.google.appengine.api.search.SearchServiceFactory;

public class DealSearchData {

	private static Index INDEX = SearchServiceFactory.getSearchService()
			.getIndex(IndexSpec.newBuilder().setName("deal"));
	private static final Logger log = Logger.getLogger(DealSearchData.class
			.getName());

	private int limit = 10;

	private int page = 1;

	private int totalResult = 0;

	private int totalReturn = 0;

	private DealModel currentItem = new DealModel();

	private List<DealModel> listResult = new ArrayList<DealModel>();

	public int getLimit() {
		return limit;
	}

	public void setLimit(int limit) {
		this.limit = limit;
	}

	public DealModel getCurrentItem() {
		return currentItem;
	}

	public void setCurrentItem(DealModel currentItem) {
		this.currentItem = currentItem;
	}

	public boolean isHasNextPage() {
		if (totalResult != 0) {
			return totalResult > (page * limit);
		} else {
			return false;
		}
	}

	public boolean isHasPreviousPage() {
		return page > 1;
	}

	public int getTotalResult() {
		return totalResult;
	}

	public int getTotalReturn() {
		return totalReturn;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public List<DealModel> getListResult() {
		return listResult;
	}

	public void setListResult(List<DealModel> listResult) {
		this.listResult = listResult;
	}

	public void prepareList() {
		try {
			listResult = new ArrayList<DealModel>();
			Query query = Query
					.newBuilder()
					.setOptions(
							QueryOptions.newBuilder().setLimit(limit)
									.setOffset(limit * (page - 1)).build())
					.build();

			Results<ScoredDocument> docResult = INDEX.search(query);
			totalResult = (int) docResult.getNumberFound();
			totalReturn = (int) docResult.getNumberReturned();
			if (docResult.getNumberFound() > 0) {
				for (ScoredDocument scoredDocument : docResult) {
					listResult.add(DealSearchEngine
							.documentToObjectByReflection(scoredDocument));
				}
			}
		} catch (Exception e) {
			System.out.println("Error when try to prepare list deal !");
			log.warning("Error when try to prepare list deal !");
			log.warning(e.toString());
			e.printStackTrace();
			listResult = new ArrayList<DealModel>();
		}
	}

	public void searchById(String id) {
		try {
			listResult = new ArrayList<DealModel>();
			Query query = Query.newBuilder()
					.setOptions(QueryOptions.newBuilder().setLimit(1).build())
					.build("dealId:" + id);
			Results<ScoredDocument> docResult = INDEX.search(query);
			if (docResult.getNumberFound() > 0) {
				for (ScoredDocument scoredDocument : docResult) {
					currentItem = DealSearchEngine
							.documentToObjectByReflection(scoredDocument);
				}
				listResult.add(currentItem);
			}
			totalReturn = 1;
			totalResult = 1;
		} catch (Exception e) {
			System.out.println("Error when try to search deal : " + id);
			log.warning("Error when try to search deal : " + id);
			log.warning(e.toString());
			e.printStackTrace();
			currentItem = null;
		}
	}

	public void searchAdvance(String name, String username, String category,
			int status) {
		try {
			StringBuilder queryString = new StringBuilder();
			boolean check = false;
			if (name != null && !name.isEmpty()) {
				if (!check) {
					queryString.append("name:" + name);
					check = true;
				} else {
					queryString.append(" AND name:" + name);
				}
			}
			if (username != null && !username.isEmpty()) {
				if (!check) {
					queryString.append("username:" + username);
					check = true;
				} else {
					queryString.append(" AND username:" + username);
				}
			}
			if (category != null && !category.isEmpty()) {
				if (!check) {
					queryString.append("category:" + category);
					check = true;
				} else {
					queryString.append(" AND category:" + category);
				}
			}
			if (status != 99) {
				if (!check) {
					queryString.append("status =" + status);
					check = true;
				} else {
					queryString.append(" AND status =" + status);
				}
			}
			System.out.println(queryString.toString());
			listResult = new ArrayList<DealModel>();
			Query query = Query.newBuilder().build(queryString.toString());
			Results<ScoredDocument> docResult = INDEX.search(query);
			totalResult = (int) docResult.getNumberFound();
			query = Query
					.newBuilder()
					.setOptions(
							QueryOptions.newBuilder().setLimit(limit)
									.setOffset(limit * (page - 1)).build())
					.build(queryString.toString());
			docResult = INDEX.search(query);
			totalReturn = (int) docResult.getNumberReturned();
			if (docResult.getNumberFound() > 0) {
				DealModel obj = new DealModel();
				for (ScoredDocument scoredDocument : docResult) {
					obj = DealSearchEngine
							.documentToObjectByReflection(scoredDocument);
					listResult.add(obj);
				}
			}
		} catch (Exception e) {
			System.out.println("Error when try to search deal !");
			log.warning("Error when try to search deal !");
			log.warning(e.toString());
			e.printStackTrace();
			listResult = new ArrayList<DealModel>();
		}
	}

}
